const reducersObj = {};
const effectsObj = {};
const actions = {};
export const allReducers = {}; // 存放所有的reducers
export function model(config) {
  const { name, state, reducers, effects } = config;
  const initialState = state;

  /* 遍历reducers
   * 得到reducersObj= {
   *     [name]:{
   *       [reducerName]:function(){}
   *     }
   *   }
   * 得到actions={
   *  [newEffectName]:(data)=>{}   为对象式action
   * }
   **/
  reducers &&
    Object.keys(reducers).forEach((reducerName) => {
      const newReducerName = getReducerName(name, reducerName);
      actions[newReducerName] = (data) => actionCreator(name, reducerName)(data);
      if (!(name in reducersObj)) {
        reducersObj[name] = {};
      }
      reducersObj[name][reducerName] = reducers[reducerName];
    });

  /* 遍历effects
   * 得到effectsObj= {
   *     [newEffectName]: true
   * }
   * 得到actions = {
   *    [newEffectName]:(action)=>(dispatch)=>{}   为函数式action
   * }
   **/
  effects &&
    Object.keys(effects).forEach((effectName) => {
      const newEffectName = getReducerName(name, effectName);
      actions[newEffectName] = (action, getState) => (dispatch) => {
        const state = getState()[name];
        return effects[effectName](action, { dispatch: dispatch }, { state });
      };
      effectsObj[newEffectName] = true;
    });

  // 生成allReducers
  allReducers[name] = (state = initialState, action) => {
    const actionName = action.type.split('/');
    const modelName = actionName[0];
    const reducerName = actionName[1];
    if (name === modelName && reducersObj[modelName] && reducerName in reducersObj[modelName]) {
      return reducersObj[modelName][reducerName](state, action);
    }
    return state;
  };
}

function actionCreator(modelName, reducerName) {
  return (data) => {
    return {
      type: getReducerName(modelName, reducerName),
      data,
    };
  };
}

function getReducerName(modelName, reducerName) {
  return `${modelName}/${reducerName}`;
}

// middleware
export function thunkMiddleware({ dispatch, getState }) {
  return (next) => (action) => {
    if (typeof action === 'function') {
      return action(dispatch, getState);
    }
    if (typeof action === 'object') {
      //如果当前action为effect
      if (effectsObj[action.type]) {
        return dispatch(actions[action.type](action, getState));
      }
    }
    return next(action);
  };
}
